package com.compose.universally.components

import android.annotation.SuppressLint
import androidx.annotation.IdRes
import androidx.compose.animation.AnimatedContentTransitionScope
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavDirections
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.NavOptions
import androidx.navigation.NavOptionsBuilder
import androidx.navigation.Navigator
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.rememberNavController

data class NavHostPageOptions(
    val controller: NavHostController, val backStackEntry: NavBackStackEntry
)

@SuppressLint("StaticFieldLeak")
var globalNavController: NavHostController? = null

@Composable
fun BaseNavHost(
    navController: NavHostController?,
    startDestination: String,
    modifier: Modifier = Modifier,
    contentAlignment: Alignment = Alignment.Center,
    route: String? = null,
    enterTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) = {
        fadeIn(animationSpec = tween(500))
    },
    exitTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) = {
        fadeOut(animationSpec = tween(500))
    },
    popEnterTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> EnterTransition) = enterTransition,
    popExitTransition: (AnimatedContentTransitionScope<NavBackStackEntry>.() -> ExitTransition) = exitTransition,
    builder: NavGraphBuilder.() -> Unit
) {
    globalNavController = navController ?: rememberNavController()
    NavHost(
        modifier = modifier,
        navController = globalNavController!!,
        startDestination = startDestination,
        contentAlignment = contentAlignment,
        route = route,
        enterTransition = enterTransition,
        exitTransition = exitTransition,
        popEnterTransition = popEnterTransition,
        popExitTransition = popExitTransition,
        builder = builder
    )
}

fun navigate(directions: NavDirections) {
    globalNavController?.navigate(directions.actionId, directions.arguments, null)
}

fun navigate(directions: NavDirections, navOptions: NavOptions?) {
    globalNavController?.navigate(directions.actionId, directions.arguments, navOptions)
}

fun navigate(directions: NavDirections, navigatorExtras: Navigator.Extras) {
    globalNavController?.navigate(directions, navigatorExtras)
}

fun navigate(route: String, builder: NavOptionsBuilder.() -> Unit) {
    globalNavController?.navigate(route, builder)
}

fun navigate(
    route: String, navOptions: NavOptions? = null, navigatorExtras: Navigator.Extras? = null
) {
    globalNavController?.navigate(route, navOptions, navigatorExtras)
}

fun popBackStack(): Boolean? {
    return globalNavController?.popBackStack()
}

fun popBackStack(@IdRes destinationId: Int, inclusive: Boolean): Boolean? {
    return globalNavController?.popBackStack(destinationId, inclusive)
}

fun popBackStack(
    @IdRes destinationId: Int, inclusive: Boolean, saveState: Boolean
): Boolean? {
    return globalNavController?.popBackStack(destinationId, inclusive, saveState)
}